//
//  AudioFileIOManager_libsndfile.cpp
//  tester2
//
//  Created by kadlubek47 on 18.08.2013.
//  Copyright (c) 2013 kadlubek47. All rights reserved.
//

#include "AudioFileIOManager_libsndfile.h"



#pragma mark read

void AudioFileIOManager_libsndfile::read ( void** channels /*out*/, const char* filePath, IAudioFileIOManager_struct& str)
{
    float* channelsLocal = (float*)*channels;
    
    //read into interleaved buffer
    recentlyReadFile_sfInfo_.format = 0;
    SNDFILE* inFile = sf_open (filePath, SFM_READ, &recentlyReadFile_sfInfo_);
    long long allLength = recentlyReadFile_sfInfo_.frames * recentlyReadFile_sfInfo_.channels;
    float* buffer = new float [allLength];
    sf_read_float(inFile, buffer, allLength);
    //.
    
    channelsLocal =  new float [allLength];
    unsigned int channLength = (unsigned int) recentlyReadFile_sfInfo_.frames;
    unsigned int numOfChann  = (unsigned int) recentlyReadFile_sfInfo_.channels;
    
    //convert from interleaved to coalescing channels
    for(unsigned int channNum = 0; channNum < numOfChann; ++channNum)
        for(unsigned int sampleNum = 0; sampleNum < channLength; ++sampleNum)
            channelsLocal[channNum*channLength + sampleNum] = buffer[ channNum%numOfChann + sampleNum*numOfChann ];
    //.
    
    //results
    str.numOfChannels  = numOfChann;
    str.sampleRate     = recentlyReadFile_sfInfo_.samplerate;
    str.channelLength  = channLength;
    *channels = (void*)channelsLocal;
    //.
}



#pragma mark write

void AudioFileIOManager_libsndfile::write  ( void*  channels, const char* filePath )
{
    float* channelsLocal = (float*)channels;
    
    SF_INFO newfile_sfInfo = recentlyReadFile_sfInfo_;
    SNDFILE* outFile = sf_open (filePath, SFM_WRITE, &newfile_sfInfo);
    
    long long blockSize = recentlyReadFile_sfInfo_.frames * recentlyReadFile_sfInfo_.channels;
    float* buffer = new float [blockSize];
    
    //convert from coalescing channels to interleaved channels
    for(unsigned int channNum = 0; channNum < recentlyReadFile_sfInfo_.channels; ++channNum)
        for(unsigned int sampleNum = 0; sampleNum < recentlyReadFile_sfInfo_.frames; ++sampleNum)
            buffer[channNum%recentlyReadFile_sfInfo_.channels + sampleNum*recentlyReadFile_sfInfo_.channels] = channelsLocal[ channNum*recentlyReadFile_sfInfo_.frames + sampleNum ];
    //.
    
    sf_write_float(outFile, buffer, blockSize);
    sf_close(outFile);
}